package com.bizmda.bizsip.app.config;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.io.resource.NoResourceException;
import com.bizmda.bizsip.app.controlrule.ControlRuleConfig;
import com.bizmda.bizsip.common.BizException;
import com.bizmda.bizsip.common.BizResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 史正烨
 */
@Slf4j
public class ControlRuleConfigMapping {
    private Map<String, ControlRuleConfig> mappings;
    private final String configPath;

    public ControlRuleConfigMapping(String configPath) throws BizException {
        this.configPath = configPath;
        this.load();
    }

    public void load() throws BizException {
        String scriptPath;
        this.mappings = new HashMap<>(16);
        List<File> files = new ArrayList<>();
        if (this.configPath == null) {
            try {
                log.info("application.yml中没有配置bizsip.config-path，从ClassPath资源/control-rule中读取校验规则");
                ClassPathResource resource = new ClassPathResource("/control-rule");
                File fileDir = resource.getFile();
                scriptPath = fileDir.getPath();
                if (fileDir.exists() && fileDir.isDirectory()) {
                    files = FileUtil.loopFiles(fileDir);
                }
            } catch (NoResourceException e) {
                log.warn("资源不存在:/control-rule");
                return;
            }
        }
        else {
            if (this.configPath.endsWith("/")) {
                scriptPath = this.configPath + "control-rule";
            }
            else {
                scriptPath = this.configPath + "/control-rule";
            }
            log.info("从{}目录中读取校验规则文件",scriptPath);
            files = FileUtil.loopFiles(scriptPath);
        }
        String suffix;

        Yaml yaml = new Yaml();
        for (File file : files) {
            suffix = FileUtil.getSuffix(file);
            if (! "yml".equalsIgnoreCase(suffix)) {
                continue;
            }
            log.info("处理控制规则文件: {}",FileUtil.getAbsolutePath(file));

            String allPath = FileUtil.normalize(file.getPath());
            String serviceId = allPath.substring(scriptPath.length(), allPath.length() - suffix.length() - 1);
            log.info("装载App服务[{}]控制规则文件", serviceId);
            Map<String,Object> map;
            try {
                map = yaml.load(new FileInputStream(file));
            } catch (FileNotFoundException e) {
                throw new BizException(BizResultEnum.CHECKRULE_FILE_NOTFOUND);
            }
            ControlRuleConfig controlRuleConfig = new ControlRuleConfig(map);
            mappings.put(serviceId, controlRuleConfig);
        }
    }

    public ControlRuleConfig getControlRuleConfig(String serviceId) {
        return this.mappings.get(serviceId);
    }

    public void putControlRuleConfig(String serviceId, ControlRuleConfig controlRuleConfig) {
        mappings.put(serviceId, controlRuleConfig);
    }

    public void removeControlRuleConfig(String serviceId) {
        mappings.remove(serviceId);
    }
}
